﻿using System;
using System.Drawing;
using System.Drawing.Drawing2D;
using System.Drawing.Imaging;
using System.IO;
using System.Text;
using Microsoft.VisualBasic;
using Microsoft.VisualBasic.CompilerServices;

namespace SortMyPictures
{
    public class EXIF
    {
        #region PropertyTagID enum

        /// <summary>
        /// PropertyTagID
        /// </summary>
        public enum PropertyTagID
        {
            /// <summary>
            /// 
            /// </summary>
            DateTime = 0x132,
            /// <summary>
            /// 
            /// </summary>
            DateTimeDigitized = 0x9004,
            /// <summary>
            /// 
            /// </summary>
            DateTimeOriginal = 0x9003,
            /// <summary>
            /// 
            /// </summary>
            GpsAltitude = 6,
            /// <summary>
            /// 
            /// </summary>
            GpsAltitudeRef = 5,
            /// <summary>
            /// 
            /// </summary>
            GpsDestBear = 0x18,
            /// <summary>
            /// 
            /// </summary>
            GpsDestBearRef = 0x17,
            /// <summary>
            /// 
            /// </summary>
            GpsDestDist = 0x1a,
            /// <summary>
            /// 
            /// </summary>
            GpsDestDistRef = 0x19,
            /// <summary>
            /// 
            /// </summary>
            GpsDestLat = 20,
            /// <summary>
            /// 
            /// </summary>
            GpsDestLatRef = 0x13,
            /// <summary>
            /// 
            /// </summary>
            GpsDestLong = 0x16,
            /// <summary>
            /// 
            /// </summary>
            GpsDestLongRef = 0x15,
            /// <summary>
            /// 
            /// </summary>
            GpsGpsDop = 11,
            /// <summary>
            /// 
            /// </summary>
            GpsGpsMeasureMode = 10,
            /// <summary>
            /// 
            /// </summary>
            GpsGpsSatellites = 8,
            /// <summary>
            /// 
            /// </summary>
            GpsGpsStatus = 9,
            /// <summary>
            /// 
            /// </summary>
            GpsGpsTime = 7,
            /// <summary>
            /// 
            /// </summary>
            GpsIFD = 0x8825,
            /// <summary>
            /// 
            /// </summary>
            GpsImgDir = 0x11,
            /// <summary>
            /// 
            /// </summary>
            GpsImgDirRef = 0x10,
            /// <summary>
            /// 
            /// </summary>
            GpsLatitude = 2,
            /// <summary>
            /// 
            /// </summary>
            GpsLatitudeRef = 1,
            /// <summary>
            /// 
            /// </summary>
            GpsLongitude = 4,
            /// <summary>
            /// 
            /// </summary>
            GpsLongitudeRef = 3,
            /// <summary>
            /// 
            /// </summary>
            GpsMapDatum = 0x12,
            /// <summary>
            /// 
            /// </summary>
            GpsSpeed = 13,
            /// <summary>
            /// 
            /// </summary>
            GpsSpeedRef = 12,
            /// <summary>
            /// 
            /// </summary>
            GpsTrack = 15,
            /// <summary>
            /// 
            /// </summary>
            GpsTrackRef = 14,
            /// <summary>
            /// 
            /// </summary>
            GpsVer = 0
        }

        #endregion

        #region PropertyTagType enum

        /// <summary>
        /// PropertyTagType
        /// </summary>
        public enum PropertyTagType
        {
            /// <summary>
            /// ASCII
            /// </summary>
            ASCII = 2,
            /// <summary>
            /// Byte
            /// </summary>
            Byte = 1,
            /// <summary>
            /// Long
            /// </summary>
            Long = 4,
            /// <summary>
            /// PixelFormat4bppIndexed
            /// </summary>
            PixelFormat4bppIndexed = 0,
            /// <summary>
            /// Rational
            /// </summary>
            Rational = 5,
            /// <summary>
            /// Short
            /// </summary>
            Short = 3,
            /// <summary>
            /// SLong
            /// </summary>
            SLONG = 9,
            /// <summary>
            /// SRational
            /// </summary>
            SRational = 10,
            /// <summary>
            /// Undefined
            /// </summary>
            Undefined = 7
        }

        #endregion

        /// <summary>
        /// Gets the date time.
        /// </summary>
        /// <param name="img">The img.</param>
        /// <returns></returns>
        public static DateTime GetDateTime(Image img)
        {
            DateTime minValue;
            try
            {
                PropertyItem propertyItem = img.GetPropertyItem(0x9003);
                ASCIIEncoding encoding = new ASCIIEncoding();
                string[] strArray =
                    encoding.GetString(propertyItem.Value, 0, propertyItem.Len - 1).Replace(" ", ":").Split(
                        new char[] {':'});
                minValue =
                    new DateTime(Conversions.ToInteger(strArray[0]), Conversions.ToInteger(strArray[1]),
                                 Conversions.ToInteger(strArray[2]), Conversions.ToInteger(strArray[3]),
                                 Conversions.ToInteger(strArray[4]), Conversions.ToInteger(strArray[5]));
            }
            catch (Exception exception1)
            {
                ProjectData.SetProjectError(exception1);
                Exception exception = exception1;
                minValue = DateTime.MinValue;
                ProjectData.ClearProjectError();
            }
            return minValue;
        }

        /// <summary>
        /// Gets the date time.
        /// </summary>
        /// <param name="ImageFileName">Name of the image file.</param>
        /// <returns></returns>
        public static DateTime GetDateTime(string ImageFileName)
        {
            FileStream stream = null;
            Image image = null;
            DateTime dateTime;
            try
            {
                stream = new FileStream(ImageFileName, FileMode.Open, FileAccess.Read);
                image = Image.FromStream(stream, false, false);
                dateTime = GetDateTime(image);
            }
            catch (Exception exception1)
            {
                ProjectData.SetProjectError(exception1);
                Exception exception = exception1;
                dateTime = DateTime.MinValue;
                ProjectData.ClearProjectError();
            }
            finally
            {
                if (stream != null)
                {
                    stream.Close();
                    stream.Dispose();
                }
                if (image != null)
                {
                    image.Dispose();
                }
            }
            return dateTime;
        }

        /// <summary>
        /// Gets the file size string.
        /// </summary>
        /// <param name="bytes">The bytes.</param>
        /// <returns></returns>
        public static string GetFileSizeString(long bytes)
        {
            double num4;
            long num2 = bytes/0x400L;
            long num3 = ((long) Math.Round((double) (((double) bytes)/1024.0)))/0x400L;
            long num = ((long) Math.Round((double) ((((double) bytes)/1024.0)/1024.0)))/0x400L;
            if (num > 0L)
            {
                num4 = ((((double) bytes)/1024.0)/1024.0)/1024.0;
                num4 *= 100.0;
                num4 = Math.Floor(num4)/100.0;
                return (Strings.Format(num4, "0.00") + " GB");
            }
            if (num3 > 0L)
            {
                num4 = (((double) bytes)/1024.0)/1024.0;
                num4 *= 100.0;
                num4 = Math.Floor(num4)/100.0;
                return (Strings.Format(num4, "0.00") + " MB");
            }
            if (num2 > 0L)
            {
                return (Conversions.ToString(num2) + " KB");
            }
            return (Conversions.ToString(bytes) + " bytes");
        }

        /// <summary>
        /// Gets the type of the image file.
        /// </summary>
        /// <param name="img">The img.</param>
        /// <returns></returns>
        public static string GetImageFileType(Image img)
        {
            string str2 = "";
            try
            {
                if (img.RawFormat.Equals(ImageFormat.Bmp))
                {
                    return ImageFormat.Bmp.ToString();
                }
                if (img.RawFormat.Equals(ImageFormat.Emf))
                {
                    return ImageFormat.Emf.ToString();
                }
                if (img.RawFormat.Equals(ImageFormat.Exif))
                {
                    return ImageFormat.Exif.ToString();
                }
                if (img.RawFormat.Equals(ImageFormat.Gif))
                {
                    return ImageFormat.Gif.ToString();
                }
                if (img.RawFormat.Equals(ImageFormat.Icon))
                {
                    return ImageFormat.Icon.ToString();
                }
                if (img.RawFormat.Equals(ImageFormat.Jpeg))
                {
                    return ImageFormat.Jpeg.ToString();
                }
                if (img.RawFormat.Equals(ImageFormat.MemoryBmp))
                {
                    return ImageFormat.MemoryBmp.ToString();
                }
                if (img.RawFormat.Equals(ImageFormat.Png))
                {
                    return ImageFormat.Png.ToString();
                }
                if (img.RawFormat.Equals(ImageFormat.Tiff))
                {
                    return ImageFormat.Tiff.ToString();
                }
                if (img.RawFormat.Equals(ImageFormat.Wmf))
                {
                    return ImageFormat.Wmf.ToString();
                }
                str2 = "";
            }
            catch (Exception exception1)
            {
                ProjectData.SetProjectError(exception1);
                Exception exception = exception1;
                str2 = "";
                ProjectData.ClearProjectError();
            }
            return str2;
        }

        /// <summary>
        /// Resizes the image.
        /// </summary>
        /// <param name="img">The img.</param>
        /// <param name="maxPixels">The max pixels.</param>
        /// <returns></returns>
        public static Image ResizeImage(Image img, int maxPixels)
        {
            int num;
            int num2;
            if (img.Width > img.Height)
            {
                num2 = maxPixels;
                num = (int) Math.Round((double) ((((double) maxPixels)/((double) img.Width))*img.Height));
            }
            else
            {
                num = maxPixels;
                num2 = (int) Math.Round((double) ((((double) maxPixels)/((double) img.Height))*img.Width));
            }
            if ((img.Width <= num2) & (img.Height <= num))
            {
                return null;
            }
            Bitmap image = new Bitmap(num2, num, img.PixelFormat);
            image.SetResolution(img.HorizontalResolution, img.VerticalResolution);
            Graphics graphics = Graphics.FromImage(image);
            graphics.SmoothingMode = SmoothingMode.HighQuality;
            graphics.InterpolationMode = InterpolationMode.HighQualityBicubic;
            graphics.PixelOffsetMode = PixelOffsetMode.HighQuality;
            Rectangle destRect = new Rectangle(0, 0, image.Width, image.Height);
            graphics.DrawImage(img, destRect, 0, 0, img.Width, img.Height, GraphicsUnit.Pixel);
            foreach (PropertyItem item in img.PropertyItems)
            {
                image.SetPropertyItem(item);
            }
            return image;
        }
    }
}